package com.caishi.lkx.user.login;

import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import com.alibaba.fastjson.JSON;
import com.caishi.lkx.common.AclResultCode;
import com.caishi.lkx.common.config.DiamondConfig;
import com.caishi.lkx.user.dto.LoginDto;
import com.caishi.lkx.user.ienum.type.UserAccountType;
import com.caishi.lkx.user.ienum.type.UserChannelType;
import com.caishi.lkx.user.model.LoginInfoModel;
import com.caishi.lkx.user.model.MemberModel;
import com.caishi.lkx.user.model.UserModel;
import com.caishi.lkx.user.service.IGroupService;
import com.caishi.lkx.user.service.ILoginInfoService;
import com.zzw.common.exception.BizException;
import com.zzw.common.exception.BizRuntimeException;

import com.caishi.lkx.user.dto.OrgLoginDto;

import org.bouncycastle.crypto.engines.SM2Engine;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;

/**
 * @Author huangpeng @Description //机构方登录 @Date 2023/10/16 13:31
 */
@Service("orgLoginService")
public class OrgLoginServiceImpl implements LoginService {
    @Value("${login.sm2.private-key}")
    private String sm2PrivateKey;

    @Value("${login.sm2.public-key}")
    private String sm2PublicKey;

    @Resource
    private DiamondConfig diamondConfig;
    @Resource
    private LoginServiceComposite loginServiceComposite;
    @Resource
    private ILoginInfoService userLoginService;
    @Resource
    private IGroupService groupService;
    private static SM2 sm2 = null;

    @PostConstruct
    public void init() {
        sm2 = new SM2(sm2PrivateKey, sm2PublicKey);
        sm2.setMode(SM2Engine.Mode.C1C2C3);
    }

    public static void main(String[] args) {
        //
        sm2 = new SM2("370292340450e0b45fdc8d4a7a3e11802ba883203b9c2fd3ce5e8a9f1e8426e7", "046576e3722a163b53b5b2c3e8211514097c5dda8d1bb4f6ded55cbb08755f78b833d449f388af22785f55b431562de49e08e248cbf47794cfed45cc8c7ef5799a");
        sm2.setMode(SM2Engine.Mode.C1C2C3);
        System.out.println(new String(sm2.decrypt("BP2RzsIx5o7wZJjiSvu2KtnlxtXjTgQV99bHELjQvFESYGjbXa9GAsNg9uR8IRAlVXWTApMSNBbIHc4txa5lgtXZY/ejubjqxr002XkG2MskE+JQdEmJ4Pi1yWW3v4hzqtBy/X4Q/2Y2530H7Hmhp5tTrOBosrhaYDQZ1Y07YkrxYWoOGnBbIDL9RlRzgl+co4a3rFN6KGkzzlVw2SWzHdnlgmBgU/7rxQ5ZSU/lEKJBXuXhIkomubEA/aPDroUmwnMFqi1QIxCuMXuy8+EzSxsiq17FMIUaXz2WEEU5rVW9OhXfhWuonv6T481ccl/1nkVSSI+tdfqOfbBJsPeUT+zeqe1yofo+", KeyType.PrivateKey)));
    }

    @Override
    public LoginInfoModel loginBase(LoginDto loginDto, HttpServletRequest request, HttpServletResponse response) throws BizException {
        // 解密
        String code = loginDto.getCode();
        if (StrUtil.isBlank(code)) throw new BizRuntimeException(AclResultCode.illegalRequest);
        if (code.contains("%2")) {
            code = new String(URLDecoder.decode(code.getBytes(StandardCharsets.UTF_8)));
        }
        String data = this.decryptStr(code);
        if (StrUtil.isBlank(data)) throw new BizRuntimeException(AclResultCode.illegalRequest);
        OrgLoginDto orgLoginDto = JSON.parseObject(data, OrgLoginDto.class);
        // 查找用户
        LoginInfoModel loginInfoModel = userLoginService.selectLoginInfoUserAccount(orgLoginDto.getUserAccount(), UserAccountType.orgLogin);
        if (null == loginInfoModel) {
            UserModel memeber = this.createMemeber(orgLoginDto);
            loginInfoModel = userLoginService.selectUserLoginInfo(memeber.getId(), UserAccountType.orgLogin);
        }

        return loginInfoModel;
    }

    /**
     * 创建用户
     *
     * @param orgLoginDto
     */
    private UserModel createMemeber(OrgLoginDto orgLoginDto) throws BizException {
        //GroupModel groupByOrgSign = groupService.getGroupByOrgSign(orgLoginDto.getCode());
        MemberModel member = new MemberModel();

        member.setChannelType(UserChannelType.sso);
        member.setName(orgLoginDto.getName());
        //member.setGroupId(groupByOrgSign.getId());
        if (StrUtil.isNotBlank(orgLoginDto.getPhone())) {
            member.setMobile(orgLoginDto.getPhone());
        }
        //LocalDateTime expire = groupService.getUserExpireTime(groupByOrgSign, PlatformType.VERS7).atTime(23, 59, 59);
        //member.setExpireTime(expire);
        LoginInfoModel loginInfoModel = userLoginService.selectLoginInfoUserAccount(orgLoginDto.getUid(), UserAccountType.username);
        UserModel userModel;
        if (null == loginInfoModel) {
            LoginInfoModel infoModel = LoginInfoModel.builder().account(orgLoginDto.getUid()).loginType(UserAccountType.username).certificate(StrUtil.isBlank(orgLoginDto.getPwd()) ? diamondConfig.getUserDefaultPassword() : orgLoginDto.getPwd()).build();
            userModel = loginServiceComposite.register(infoModel, member).toUserModel();
            userLoginService.userAddNewLogin(orgLoginDto.getUserAccount(), orgLoginDto.getCode(), UserAccountType.orgLogin, userModel.getId());
        } else {
            //如果用户名被占用就不生成用户名
            LoginInfoModel infoModel = LoginInfoModel.builder().account(orgLoginDto.getUserAccount()).loginType(UserAccountType.orgLogin).certificate(orgLoginDto.getCode()).build();
            userModel = loginServiceComposite.register(infoModel, member).toUserModel();
        }
        return userModel;

    }

    /**
     * code解密
     *
     * @param code
     * @return
     */
    public String decryptStr(String code) {
        try {
            return new String(sm2.decrypt(code, KeyType.PrivateKey));
        } catch (Exception e) {
            return null;
        }
    }
}
